
#ifndef RTUTILCLASSES_H
#define RTUTILCLASSES_H

#include "RtDefines.h"
#include "RtThreadInterface.h"
#include "RtStdCpp.h"

class CRtMutexThreadRecursive;
class CRtThread;

class RT_API_EXPORT CRtEnsureSingleThread
{
public:
	CRtEnsureSingleThread();
	void EnsureSingleThread() const;
	void Reset2CurrentThreadId();
	void Reset2ThreadId(RT_THREAD_ID aTid);

protected:
	RT_THREAD_ID m_ThreadIdOpen;
};

class RT_API_EXPORT CRtStopFlag
{
public:
	CRtStopFlag() : m_bStoppedFlag(TRUE)
	{
	}

	void SetStartFlag();

	void SetStopFlag();

	BOOL IsFlagStopped() const
	{
		m_Est.EnsureSingleThread();
		return m_bStoppedFlag;
	}
	
	CRtEnsureSingleThread m_Est;
	BOOL m_bStoppedFlag;
};

class RT_API_EXPORT CRtSignalStop : public IRtEvent
{
public:
	static CRtSignalStop* Instance();

	virtual ~CRtSignalStop();

	// Do the stop work.
	RtResult Launch(int aSig);
	
	// interface IRtEvent.
	virtual RtResult OnEventFire();

	virtual void OnDestorySelf();

private:
	CRtSignalStop();

	static CRtSignalStop s_rtSignalStopSingleton;
	CRtThread *m_pThread;
};

class CRtErrnoGuard
{
public:
	CRtErrnoGuard() : m_nErr(errno)
	{
	}

	~CRtErrnoGuard()
	{
		errno = m_nErr;
	}
private:
	int m_nErr;
};

class RT_API_EXPORT CRtCleanUpBase
{
public:
	static void CleanupAll();

protected:
	CRtCleanUpBase();
	virtual ~CRtCleanUpBase();
	virtual void CleanUp();

private:
	CRtCleanUpBase *m_pNext;
	static CRtCleanUpBase *s_pHeader;

private:
	typedef CRtMutexThreadRecursive MutexType;
	
	// = Prevent assignment and initialization.
	void operator = (const CRtCleanUpBase&);
	CRtCleanUpBase(const CRtCleanUpBase&);
};

class RT_API_EXPORT CRtDataBlockNoMalloc
{
public:
	CRtDataBlockNoMalloc(LPCSTR aStr, DWORD aLen);

	/// Read and advance <aCount> bytes, 
	RtResult Read(LPVOID aDst, DWORD aCount, DWORD *aBytesRead = NULL);

	/// Write and advance <aCount> bytes
	RtResult Write(LPCVOID aSrc, DWORD aCount, DWORD *aBytesWritten = NULL);
	
private:
	LPCSTR m_pBegin;
	LPCSTR m_pEnd;
	LPCSTR m_pCurrentRead;
	LPSTR m_pCurrentWrite;
};

#endif // !RTUTILCLASSES_H
